package plp.functional1.expression;

import plp.expressions1.util.Tipo;
import plp.expressions2.expression.Expressao;
import plp.expressions2.expression.Valor;
import plp.expressions2.expression.ValorInteiro;
import plp.expressions2.memory.AmbienteCompilacao;
import plp.expressions2.memory.AmbienteExecucao;
import plp.expressions2.memory.VariavelJaDeclaradaException;
import plp.expressions2.memory.VariavelNaoDeclaradaException;
import plp.functional1.memory.AmbienteExecucaoFuncional;
import plp.functional2.expression.MapException;

public class ExpElementoTupla implements Expressao {

	private Expressao expressao1;
	private Expressao expressao2;
	private ValorTupla valor;

	public ExpElementoTupla(Expressao exp1, Expressao exp2) {
		expressao1 = exp1;
		expressao2 = exp2;		
	}
	
	public Valor avaliar(AmbienteExecucao amb)
			throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException, TuplaException, MapException {
		AmbienteExecucaoFuncional ambienteFuncional =
			(AmbienteExecucaoFuncional) amb;
		
		try {
			
		valor = (ValorTupla)expressao1.avaliar(ambienteFuncional);
		return valor.get(((ValorInteiro)expressao2.avaliar(ambienteFuncional)).valor().intValue());
		
		} catch (ClassCastException cce) {
			throw new TuplaException("erro de tipo.");
		}
	}

	public boolean checaTipo(AmbienteCompilacao amb)
			throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
		return expressao2.getTipo(amb).eInteiro();
	}

	public Tipo getTipo(AmbienteCompilacao amb)
			throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
		
		return valor.getTipo(amb);
	}

}
